package bg.openid;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openid4java.consumer.ConsumerException;
import org.openid4java.consumer.ConsumerManager;
import org.openid4java.consumer.VerificationResult;
import org.openid4java.discovery.DiscoveryInformation;
import org.openid4java.discovery.Identifier;
import org.openid4java.message.AuthSuccess;
import org.openid4java.message.Parameter;
import org.openid4java.message.ParameterList;
import org.openid4java.message.ax.AxMessage;
import org.openid4java.message.ax.FetchResponse;

public class ServletOpenidReturn extends HttpServlet {

	private ConsumerManager manager;
	private ServletContext context;
	public static final String OPENID_NS_SREG1_1 = "http://openid.net/extensions/sreg/1.1";

	private static Log log = LogFactory.getLog("ServletOpeniDReturn");

	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		context = config.getServletContext();
		System.out.println("ConsumerServlet context: " + context);
		try {
			// this.manager = new ConsumerManager();
			this.manager = ServletOpenid.manager;
		} catch (Exception e) {
			throw new ServletException(e);
		}
	}

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		log("ServletOpenidReturn.doGet");
		System.err.println("ServletOpenIdReturn.doGet ContentLength :--------------------" + request.getContentLength());
		System.err.println("ServletOpenIdReturn.doGet RemoteAddr :-----------------------" + request.getRemoteAddr());
		System.err.println("ServletOpenIdReturn.doGet LocalAddr :-----------------------" + request.getLocalAddr());
		System.err.println("ServletOpenIdReturn.doGet PathInfo :-------------------------" + request.getPathInfo());
		System.err.println("ServletOpenIdReturn.doGet QueryString :----------------------" + request.getQueryString());
		System.err.println("ServletOpenIdReturn.doGet -----------------------------------" + request.getParameterMap());
		System.err.println("ServletOpenIdReturn.doGet ---request.getParameterMap().size: " + request.getParameterMap().size());
		if (request.getQueryString() == null) {
			response.getWriter().write("");
			response.getWriter().close();
			return;
		}
		doPost(request, response);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		log("ServletOpenidReturn.doPost");
		Bean bean = (Bean) request.getSession().getAttribute("bean");
		if (bean == null) {
			bean = new Bean();
			request.getSession().setAttribute("bean", bean);
		}
		try {
			this.processOpenIdResponse(request, response, bean);
		} catch (Exception e) {
			log("Exeception " + e.getMessage());
			e.printStackTrace();
			bean.addException(e);
		}
		RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/bg2.jsp");
		dispatcher.forward(request, response);
	}

	private void processOpenIdResponse(HttpServletRequest request, HttpServletResponse response, Bean bean) throws Exception {

		bean.addComment("return from OpenId");
		bean.display(request);
		// extract the parameters from the authentication response
		// (which comes in as a HTTP request from the OpenID provider)
		ParameterList openidResp = new ParameterList(request.getParameterMap());
		//bean.display(openidResp);
		// retrieve the previously stored discovery information
		HttpSession session = request.getSession();
		DiscoveryInformation discovered = (DiscoveryInformation) session.getAttribute("discovered");
		bean.addComment("discovered: ", discovered);
		StringBuffer receivingURL = request.getRequestURL();
		String queryString = request.getQueryString();
		if (queryString != null && queryString.length() > 0) {
			receivingURL.append("?").append(request.getQueryString());
		}
		bean.addComment("queryString: ", queryString);
		bean.addComment("receivingURL: ", receivingURL);
		bean.addComment("openidResp: ", openidResp);
		
		// verify the response
		VerificationResult verification = manager.verify(receivingURL.toString(), openidResp, discovered);
		bean.addComment("verification: ", verification);
		bean.addComment("verification.getStatusMsg: ", verification.getStatusMsg());
		bean.addComment("verification.getVerifiedId: ", verification.getVerifiedId());

		// examine the verification result and extract the verified identifier
		Identifier verified = verification.getVerifiedId();
		bean.addComment("verified: ", verified);

		if (verified == null) {
			bean.addComment("No identified!! ");
		} else {
			bean.addComment("Identification OK !! ");
			AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
			bean.addComment("AxMessage.OPENID_NS_AX :" + AxMessage.OPENID_NS_AX, "" + authSuccess.hasExtension(AxMessage.OPENID_NS_AX));
			boolean b = authSuccess.hasExtension(AxMessage.OPENID_NS_AX);
			if (b) {
				FetchResponse fetchResp = (FetchResponse) authSuccess.getExtension(AxMessage.OPENID_NS_AX);

				List emails = fetchResp.getAttributeValues("email");
				bean.addComment("emails", emails);
				// String email = (String) emails.get(0);

				List aliases = fetchResp.getAttributeAliases();
				for (Iterator iter = aliases.iterator(); iter.hasNext();) {
					String alias = (String) iter.next();
					List values = fetchResp.getAttributeValues(alias);
					if (values.size() > 0) {
						log.debug(alias + " : " + values.get(0));
						request.setAttribute(alias, values.get(0));
						bean.addComment(alias, values.get(0));
					}
				}
			}
			boolean bb = authSuccess.hasExtension(OPENID_NS_SREG1_1);
			bean.addComment("OPENID_NS_SREG1_1:" + OPENID_NS_SREG1_1, "" + bb);
			
			if (bb) {
				bean.addComment("email:" ,authSuccess.getParameterValue("openid.sreg.email"));
				bean.addComment("got info:" , authSuccess.getParameterValue("openid.sreg.fullname"));

			}

		}
	}

}
